package com.service.sys;

import com.common.utils.Constants;
import com.common.ErrorCodeEnum;
import com.common.emums.DataStatus;
import com.common.exception.BusinessException;
import com.common.utils.Md5Utils;
import com.common.utils.StringUtils;
import com.core.springSecurity.common.SecurityUtils;
import com.dao.sys.SysUserMapper;
import com.model.domain.sys.GetUserListDO;
import com.github.pagehelper.PageHelper;
import com.model.pojo.sys.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class SysUserService {
    @Resource
    private SysUserMapper userMapper;

    /**密码加密*/
   private final BCryptPasswordEncoder passwordEncoder =new BCryptPasswordEncoder();

    public SysUser get(Long userId){
        return userMapper.selectByPrimaryKey(userId,null);
    }

    /**
     * @Author: zql
     * @Description: 通过用户名或手机号查询
     * @param loginName 手机号或用户名或邮箱
     * @Data: 9:52 2021/5/11
     */
    public SysUser getByNameOrMobileOrEmail(String loginName){
        PageHelper.clearPage();
        SysUser sysUser = userMapper.selectByLoginName(loginName);
        return sysUser;
    }

    /**
     * @Author: zql
     * @Description: 通过手机号查询
     * @param email 邮箱
     * @Data: 8:47 2021/8/2
     */
    public SysUser getByEmail(String email){
        PageHelper.clearPage();
        SysUser sysUser = userMapper.select(null,null,null,email,DataStatus.OK.getCode());
        if(StringUtils.isNull(sysUser)){
            throw new BusinessException(ErrorCodeEnum.USER_DATA_NOT_FOUND);
        }
        return sysUser;
    }

    /**
     * @Author: zql
     * @Description: 通过手机号查询
     * @param mobile 手机号
     * @Data: 8:47 2021/8/2
     */
    public SysUser getByMobile(String mobile){
        PageHelper.clearPage();
        SysUser sysUser = userMapper.select(null,null,mobile,null,DataStatus.OK.getCode());
        if(StringUtils.isNull(sysUser)){
            throw new BusinessException(ErrorCodeEnum.USER_DATA_NOT_FOUND);
        }
        return sysUser;
    }

    /**
     * @Author: zql
     * @Description: 通过登录用户名查询
     * @param name 登录名
     * @Data: 17:39 2021/5/10
     */
    public SysUser getByName(String name) {
        PageHelper.clearPage();
        SysUser sysUser =  userMapper.select(null,name,null,null,null);
        if(StringUtils.isNull(sysUser)){
            throw new BusinessException(ErrorCodeEnum.USER_DATA_NOT_FOUND);
        }
        return sysUser;
    }
    /**
     * @Author: zql
     * @Description: 查询部门人员总数
     * @param sysDeptId 部门id
     * @Data: 8:54 2021/12/8
     */
    public int getCountByDeptId(Long sysDeptId){
        return userMapper.getCountByDept(sysDeptId);
    }

    /**
     * @Author: zql
     * @Description: 根据条件查询用户列表
     * @param getUserListDO 查询条件对象
     * @Data: 9:57 2021/5/11
     */
    public List<SysUser> getUser(GetUserListDO getUserListDO){
        PageHelper.clearPage();
        PageHelper.startPage(getUserListDO.getPage(), getUserListDO.getPageSize(),getUserListDO.getSortRow()+getUserListDO.getSortOrder());
        return userMapper.selectUserList(getUserListDO);
    }

    public boolean hasEmail(String email){
        return userMapper.hasEmail(email, DataStatus.OK.getCode()) > 0;
    }

    public boolean hasName(String name){
        return userMapper.hasName(name, DataStatus.OK.getCode()) > 0;
    }

    public boolean hasDept(Long sysDeptId){
        return userMapper.hasDeptId(sysDeptId, DataStatus.OK.getCode()) > 0;
    }

    public boolean hasMobile(String mobile){
        return userMapper.hasMobile(mobile, DataStatus.OK.getCode()) > 0;
    }

    public boolean has(Long sysUserId){
        return userMapper.has(sysUserId, DataStatus.OK.getCode()) > 0;
    }

    public boolean has(Long sysUserId,Byte isDelete){
        return userMapper.has(sysUserId, isDelete) > 0;
    }

    public void updateAndInsert(List<SysUser> sysUserList){
        List<SysUser> updateSysUserList=new ArrayList<>();
        List<SysUser> createSysUserList=new ArrayList<>();
        sysUserList.forEach( o-> {
                    if (StringUtils.isNotNull(o.getSysUserId()) &&userMapper.has(o.getSysUserId(),null) > 0){
                        updateSysUserList.add(o);
                    } else{
                        createSysUserList.add(o);
                    }
                }
        );
        if(updateSysUserList.size()>0){
            updateList(updateSysUserList);
        }
        if(createSysUserList.size()>0){
            createList(createSysUserList);
        }
    }

    /**
     * @Author: zql
     * @Description: 创建用户列表
     * @param sysUserList 用户列表
     * @Data: 9:52 2021/5/11
     */
    public void createList(List<SysUser> sysUserList) {
        String name=SecurityUtils.getUsername();
        sysUserList.forEach(o->{
            o.setCreator(name);
            o.setModifier(name);
            o.setUpdateTime(null);
            o.setCreateTime(null);
        });
        userMapper.insertList(sysUserList);
    }

    /**
     * @Author: zql
     * @Description: 创建新用户
     * @param sysUser 用户
     * @Data: 10:00 2021/5/11
     */
    public void create(SysUser sysUser) {
        String name=SecurityUtils.getUsername();
        sysUser.setUpdateTime(null);
        sysUser.setCreateTime(null);
        sysUser.setCreator(name);
        sysUser.setModifier(name);
        userMapper.insertSelective(sysUser);
    }

    /**
     * @Author: zql
     * @Description: 注册新用户
     * @param sysUser 用户对象
     * @Data: 16:04 2021/7/21
     */
    public void register(SysUser sysUser) {
        sysUser.setUpdateTime(null);
        sysUser.setCreateTime(null);
        sysUser.setCreator(Constants.USER);
        sysUser.setModifier(Constants.USER);
        userMapper.insertSelective(sysUser);
    }

    /**
     * @Author: zql
     * @Description: 更新用户信息
     * @param sysUser 用户
     * @Data: 9:59 2021/5/11
     */
    public void update(SysUser sysUser){
        sysUser.setModifier(SecurityUtils.getUsername());
        sysUser.setUpdateTime(null);
        sysUser.setCreateTime(null);
        sysUser.setCreator(null);
        userMapper.updateByPrimaryKeySelective(sysUser);
    }

    /**
     * @Author: zql
     * @Description: 更新用户密码
     * @param sysUserId 用户id
     * @param newPassword 未加密的新密码
     * @Data: 9:59 2021/5/11
     */
    public void resetPassword(Long sysUserId,String newPassword){
        SysUser sysUser = new SysUser();
        sysUser.setSysUserId(sysUserId);
        sysUser.setPassword(encode(Md5Utils.toUpperCase32(newPassword)));
        sysUser.setModifier(Constants.USER);
        userMapper.updateByPrimaryKeySelective(sysUser);
    }

    public void resetMobile(Long sysUserId,String mobile){
        SysUser sysUser = new SysUser();
        sysUser.setSysUserId(sysUserId);
        sysUser.setMobile(mobile);
        sysUser.setModifier(Constants.USER);
        userMapper.updateByPrimaryKeySelective(sysUser);
    }

    public void resetEmail(Long sysUserId,String email){
        SysUser sysUser = new SysUser();
        sysUser.setSysUserId(sysUserId);
        sysUser.setEmail(email);
        sysUser.setModifier(Constants.USER);
        userMapper.updateByPrimaryKeySelective(sysUser);
    }

    /**
     * @Author: zql
     * @Description: 批量更新用户信息
     * @param sysUserList 用户列表
     * @Data: 11:49 2021/5/6
     */
    public void updateList(List<SysUser> sysUserList) {
        String name=SecurityUtils.getUsername();
        sysUserList.forEach(o->{
            o.setCreator(name);
            o.setModifier(name);
            o.setUpdateTime(null);
            o.setCreateTime(null);
        });
        userMapper.updateByPrimaryKeySelectiveList(sysUserList);
    }

    /**
     * @Author: zql
     * @Description: 密码加密
     * @param password 密码
     * @Data: 17:06 2021/6/30
     */
    public String encode(String password){
        return  passwordEncoder.encode(password);
    }

    /**
     * @Author: zql
     * @Description: 密码校验
     * @param oldPassword 旧密码（经过MD5加密）
     * @param encodePassword 经过加密的密码
     * @Data: 8:57 2021/7/1
     */
    public boolean matches(String oldPassword,String encodePassword){
        return passwordEncoder.matches(oldPassword, encodePassword);
    }
    /**
     * @param sysUser 用户
     * @param toUpdate 确认验证的用户为新增用户或更新用户
     * @Author: zql
     * @Description: 用户信息验证，
     * @Data: 10:08 2021/6/22
     */
    public void verifyUserInfo(SysUser sysUser, boolean toUpdate) {
        boolean toInsert = !toUpdate;

        if (toUpdate && (StringUtils.isNull(sysUser.getSysUserId()) || userMapper.has(sysUser.getSysUserId(), null) == 0)) {
            log.error("用户不存在，用户信息更新失败，id:{}", sysUser.getSysUserId());
            throw new BusinessException(ErrorCodeEnum.DATA_NOT_FOUNT);
        }

        if (StringUtils.isNotNull(sysUser.getName())) {
            if (sysUser.getName().length() > Constants.VARCHAR_LENGTH_50) {
                throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("登录名过长:maxLength:" +
                        Constants.VARCHAR_LENGTH_50 +
                        " length:" + sysUser.getName().length()));
            }
            SysUser sysUserDB = userMapper.select(null, sysUser.getName(), null, null, DataStatus.OK.getCode());
            if (toInsert && StringUtils.isNotNull(sysUserDB) ||
                    toUpdate && StringUtils.isNotNull(sysUserDB) && !sysUserDB.getSysUserId().equals(sysUser.getSysUserId())) {
                log.error("登录用户名重复:{}", sysUser.getName());
                throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("登录用户名重复:name:" + sysUser.getName()));
            }
        } else if (toInsert) {
            log.error("新增用户登录用户名不能为空:{}", sysUser.getName());
            throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("新增用户登录用户名不能为空"));
        }

        if (StringUtils.isNotEmpty(sysUser.getMobile())) {
            verifyMobileFormat(sysUser.getMobile());
            SysUser sysUserDB = userMapper.select(null, null, sysUser.getMobile(), null, DataStatus.OK.getCode());
            if (toInsert && StringUtils.isNotNull(sysUserDB) ||
                    toUpdate && StringUtils.isNotNull(sysUserDB) && !sysUserDB.getSysUserId().equals(sysUser.getSysUserId())) {
                log.error("手机号重复:{}", sysUser.getMobile());
                throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("手机号重复:" + sysUser.getMobile()));
            }
        }

        if (StringUtils.isNotEmpty(sysUser.getEmail())) {
            verifyEmailFormat(sysUser.getEmail());
            SysUser sysUserDB = userMapper.select(null, null, null, sysUser.getEmail(), DataStatus.OK.getCode());
            if (toInsert && StringUtils.isNotNull(sysUserDB) ||
                    toUpdate && StringUtils.isNotNull(sysUserDB) && !sysUserDB.getSysUserId().equals(sysUser.getSysUserId())) {
                log.error("邮箱重复:{}", sysUser.getEmail());
                throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("邮箱重复:" + sysUser.getEmail()));
            }
        }


        if (toInsert && StringUtils.isEmpty(sysUser.getFullName())) {
            log.error("新增用户显示名称不能为空:{}", sysUser.getName());
            throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("新增用户显示名称不能为空"));
        }

        if (StringUtils.isNotNull(sysUser.getIsDelete()) && !DataStatus.contains(sysUser.getIsDelete())) {
                log.error("数据状态设置错误:{}", sysUser.getIsDelete());
                throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("数据状态设置错误"));
        }

        if (StringUtils.isNotNull(sysUser.getImagePath())  && sysUser.getImagePath().length() > Constants.VARCHAR_LENGTH_255) {
                log.error("图片路径过长 path:{}", sysUser.getImagePath().length());
                throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("图片路径过长:maxLength:" + Constants.VARCHAR_LENGTH_255 +
                        " length:" + sysUser.getImagePath().length()));
        }

        if (StringUtils.isNotNull(sysUser.getFullName()) && sysUser.getFullName().length() > Constants.VARCHAR_LENGTH_128) {
                log.error("显示名称过长 fullName:{}", sysUser.getFullName().length());
                throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("显示名称过长:maxLength:" + Constants.VARCHAR_LENGTH_128 +
                        " length:" + sysUser.getFullName().length()));
        }


        if (StringUtils.isNotNull(sysUser.getPassword())) {
            if (sysUser.getPassword().length() > Constants.VARCHAR_LENGTH_255) {
                log.error("密码过长 password:{}", sysUser.getPassword().length());
                throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("密码过长:maxLength:" + Constants.VARCHAR_LENGTH_255 +
                        " length:" + sysUser.getPassword().length()));
            }
        } else if (toInsert) {
            log.error("新增用户密码不能为空");
            throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("新增用户密码不能为空"));
        }

        if (StringUtils.isNotNull(sysUser.getIp())) {
            if (sysUser.getIp().length() > Constants.VARCHAR_LENGTH_50) {
                log.error("ip过长 ip:{}", sysUser.getIp().length());
                throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("ip过长:maxLength:" + Constants.VARCHAR_LENGTH_50 +
                        " length:" + sysUser.getIp().length()));
            }
        }
    }

    /**
     * @Author: zql
     * @Description: 手机号校验
     * @param mobile 手机号
     * @Data: 15:19 2021/7/1
     */
    public void verifyMobileFormat(String mobile){
        if (StringUtils.isEmpty(mobile)) {
            log.error("手机号不能为空");
            throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("手机号不能为空"));
        }
        if (mobile.length() != 11) {
            log.error("手机号只能是11位:{}", mobile);
            throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("手机号只能是11位:"+mobile));
        }
        if (!mobile.matches("^[0-9]*$")) {
            log.error("手机号非法:{}", mobile);
            throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("手机号非法:"+mobile));
        }
    }

    public void verifyEmailFormat(String email){
        if (StringUtils.isEmpty(email)) {
            log.error("邮箱不能为空");
            throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("邮箱不能为空"));
        }
        if (email.length() > Constants.VARCHAR_LENGTH_50) {
            log.error("邮箱过长 email:{}", email.length());
            throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("邮箱过长:maxLength:" + Constants.VARCHAR_LENGTH_50 +
                    " length:" + email.length()));
        }
        if (!email.matches("\\b[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]{2,6}\\b")) {
            log.error("邮箱非法:{}", email);
            throw new BusinessException(ErrorCodeEnum.USER_VERIFY.setParam("邮箱非法:"+email));
        }
    }

}
